﻿namespace NMortgage.UI.ViewModels
{
    using System;
    using System.ComponentModel.Composition;
    using System.Linq;

    using Caliburn.Micro;

    using Microsoft.Practices.Unity;

    using NMortgage.UI.Model;
    using NMortgage.UI.Events;

    public sealed class LoanProfileViewModel : BaseViewModel, IHandle<ProfileItemAdded>
    {
        #region Fields

        private double _loanAmount;
        private PaymentFrequency _selectedPaymentFrequency;
        private int _termLength;
        private double _estimatedTotal;
        private double _estimatedInterest;
        private IEventAggregator eventAggregator;

        #endregion Fields

        public LoanProfileViewModel(IEventAggregator eventAggregator) {
            this.eventAggregator = eventAggregator;
            this.eventAggregator.Subscribe(this);
        }

        #region Properties

        public Array AvailableFrequencies
        {
            get { return Enum.GetValues(typeof(PaymentFrequency)); }
        }

        [Dependency]
        public InterestParameterListViewModel InterestRates
        {
            get;
            set;
        }

        [Dependency]
        public FeeListViewModel Fees
        {
            get;
            set;
        }

        [Dependency]
        public ExtraPaymentListViewModel Payments
        {
            get;
            set;
        }

        public double LoanAmount
        {
            get { return _loanAmount; }
            set
            {
                _loanAmount = value;
                OnLoanProfileChanged();
            }
        }

        public MortgageProfile LoanProfile
        {
            get
            {
                return new MortgageProfile()
                       {
                           LoanAmount = this.LoanAmount,
                           PaymentFrequency = this.SelectedPaymentFrequency,
                           StartDate = this.StartDate.GetValueOrDefault(DateTime.Today),
                           InterestRates = this.InterestRates.ItemCollection,
                           ExtraPayments = this.Payments.ItemCollection.ToList(),
                           TermLength = this.TermLength
                       };
            }
        }

        public PaymentFrequency SelectedPaymentFrequency
        {
            get { return _selectedPaymentFrequency; }
            set
            {
                _selectedPaymentFrequency = value;
                OnLoanProfileChanged();
            }
        }

        public DateTime? StartDate
        {
            get;
            set;
        }

        public int TermLength
        {
            get { return _termLength; }
            set
            {
                _termLength = value;
                OnLoanProfileChanged();
            }
        }

        public override string Title
        {
            get
            {
                return Properties.Resources.LoadProfileTitle;
            }
        }

        public double EstimatedTotalPayback
        {
            get
            {
                return _estimatedTotal;
            }
            private set
            {
                _estimatedTotal = value;
                NotifyOfPropertyChange(() => EstimatedTotalPayback);
            }
        }

        public double EstimatedInterest
        {
            get
            {
                return _estimatedInterest;
            }
            private set
            {
                _estimatedInterest = value;
                NotifyOfPropertyChange(() => EstimatedInterest);
            }
        }

        private double _estimatedPeriodicPayment;
        public double EstimatedPeriodicPayment
        {
            get 
            {
                return _estimatedPeriodicPayment;
            }
            set 
            {
                _estimatedPeriodicPayment = value;
                NotifyOfPropertyChange(() => EstimatedPeriodicPayment);
            
            }
        }
        #endregion Properties

        #region Methods

        private void OnLoanProfileChanged()
        {
            var firstRate = InterestRates.ItemCollection.FirstOrDefault();
            OnLoanProfileChanged(firstRate);
        }
        private void OnLoanProfileChanged(IInterestRate rate)
        {
            //IInterestRate rate
            if (rate == null) { return; }
            //{
            //    EstimatedTotalPayback = 0;
            //    EstimatedPeriodicPayment = 0;
            //    EstimatedInterest = 0;
            //    return;
            //}
            
            int annualPeriods = ((SelectedPaymentFrequency == PaymentFrequency.Monthly) ? 12 : 26);
            int periodicFactor = ((SelectedPaymentFrequency == PaymentFrequency.Monthly) ? 1 : 2);

            double sampleRate = rate.Distribution.GetRate() / 12;
            double basicAnnuity = MortgageCalculator.CalculateAnnuity(TermLength, sampleRate, LoanAmount);
            basicAnnuity = basicAnnuity / periodicFactor;

            EstimatedTotalPayback = basicAnnuity * TermLength * annualPeriods;
            EstimatedInterest = EstimatedTotalPayback - LoanAmount;

            EstimatedPeriodicPayment = basicAnnuity;
        }

        #endregion Methods

        public void Handle(ProfileItemAdded message)
        {
            if (message != null ){
                IInterestRate rate = message.Item as IInterestRate;
                OnLoanProfileChanged(rate);
            }
        }
    }
}